﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using SolutionExtender.AppCode;
using SolutionExtender.Interfaces;

namespace McTools.SolutionExtender.UserQueryToSystemPlugin
{
    public partial class UserQueryToSystemExportControl : UserControl, IExportControl
    {
        #region Variables

        /// <summary>
        /// Microsoft Dynamics CRM 2011 Organization service
        /// </summary>
        private readonly IOrganizationService _service;

        /// <summary>
        /// Indicates if this control found rules
        /// </summary>
        private bool _hasData;

        #endregion Variables

        #region Constructor

        /// <summary>
        /// Initializes a new instance of class UserQueryExportControl
        /// </summary>
        /// <param name="service">Microsoft Dynamics CRM 2011 Organization service</param>
        public UserQueryToSystemExportControl(IOrganizationService service)
        {
            _service = service;
            InitializeComponent();
        }

        #endregion Constructor

        #region Methods

        /// <summary>
        /// Loads list of user queries
        /// </summary>
        private void UserQueryControlLoad(object sender, EventArgs e)
        {
            var items = new List<ListViewItem>();

            var qba = new QueryByAttribute("userquery");
            qba.Attributes.Add("querytype");
            qba.Values.Add(UserQueryQueryType.CustomDefinedView);
            qba.ColumnSet = new ColumnSet(true);

            var qe = new QueryExpression("userquery");
            qe.ColumnSet = new ColumnSet(true);

            var collection = _service.RetrieveMultiple(qe);

            foreach (var rule in collection.Entities)
            {
                var item = new ListViewItem(rule["name"].ToString());
                item.SubItems.Add(rule["returnedtypecode"].ToString());
                item.SubItems.Add(rule.Contains("description") ? rule["description"].ToString() : "");
                item.Tag = rule.Id;

                items.Add(item);
            }

            if (items.Count() == 0)
            {
                _hasData = false;
                lvItems.Visible = false;
                pnlNoItems.Visible = true;
            }
            else
            {
                _hasData = true;
                pnlNoItems.Visible = false;
                lvItems.Items.AddRange(items.ToArray());
            }
        }

        /// <summary>
        /// Gets a Xml list of selected user queries
        /// </summary>
        /// <returns></returns>
        public XmlNodeList GetSelectedItems()
        {
            if (lvItems.SelectedItems.Count == 0 && _hasData)
            {
                pnlError.Visible = true;
                return null;
            }

            pnlError.Visible = false;
            var stringifiedXml = new StringBuilder();
            stringifiedXml.Append("<Root>");

            foreach (ListViewItem item in lvItems.SelectedItems)
            {
                // Retrieve duplicate detection rule
                var query = _service.Retrieve("userquery", (Guid)item.Tag, new ColumnSet(true));

                var queryObject = new UserQuery
                {
                    AdvancedGroupBy = query.Contains("advancedgroupby") ? query["advancedgroupby"].ToString() : string.Empty,
                    ColumnSetXml = query.Contains("columnsetxml") ? query["columnsetxml"].ToString() : string.Empty,
                    ConditionalFormatting = query.Contains("conditionalformatting") ? query["conditionalformatting"].ToString() : string.Empty,
                    Description = query.Contains("description") ? query["description"].ToString() : string.Empty,
                    FetchXml = query.Contains("fetchxml") ? query["fetchxml"].ToString() : string.Empty,
                    LayoutXml = query.Contains("layoutxml") ? query["layoutxml"].ToString() : string.Empty,
                    Name = query.Contains("name") ? query["name"].ToString() : string.Empty,
                    QueryType = 0,
                    ReturnedTypeCode = query.Contains("returnedtypecode") ? query["returnedtypecode"].ToString() : string.Empty
                };

                var tempDoc = new XmlDocument();
                tempDoc.LoadXml(XmlSerializerHelper.Serialize(queryObject));

                stringifiedXml.Append(tempDoc.DocumentElement.OuterXml);
            }

            stringifiedXml.Append("</Root>");

            var doc = new XmlDocument();
            doc.LoadXml(stringifiedXml.ToString());

            return doc.DocumentElement.ChildNodes;
        }

        #endregion Methods

        #region Handlers

        private void LvItemsColumnClick(object sender, ColumnClickEventArgs e)
        {
            lvItems.Sorting = lvItems.Sorting == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;

            lvItems.ListViewItemSorter = new ListViewItemComparer(e.Column, lvItems.Sorting);
        }

        #endregion Handlers
    }
}
